﻿/*    
    OpenMheg - A free MHEG-5 library
    Copyright (C) 2008 Dharmesh Malam

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Text;
using ASN1Decoder.Builders.Nodes;
using Core.Model;
using Core.Model.Data;
using Engine;
using Core.Model.Groups;
using Core.Model.Ingredients.Presentable.Visibles;

namespace ASN1Decoder.Builders.Visibles
{
    internal class TextBuilder
    {
        internal static Text Build (TaggedNode node, Group group)
        {
            var text = new Text();
            VisibleBuilder.Build(node, text, group);

            TaggedNode e;

            if((e = node[ASN1ContextCodes.C_ORIGINAL_FONT]) != null)
                text.OriginalFont = e.First.StringValue;

            if((e = node[ASN1ContextCodes.C_FONT_ATTRIBUTES]) != null)
                text.OriginalFontAttributes = FontAttributesBuilder( (OctetStringNode) e.First );
            
            if((e = node[ASN1ContextCodes.C_TEXT_COLOUR]) != null)
                text.OriginalTextColour = ColourBuilder.Build( e.First , group);

            if((e = node[ASN1ContextCodes.C_BACKGROUND_COLOUR]) != null)
                text.OriginalBackgroundColour = ColourBuilder.Build( e.First , group);

            if((e = node[ASN1ContextCodes.C_CHARACTER_SET]) != null)
                text.CharacterSet = e.First.IntValue;

            if((e = node[ASN1ContextCodes.C_HORIZONTAL_JUSTIFICATION]) != null)
                text.HorizontalJustification = ParseJustification( e );

            if((e = node[ASN1ContextCodes.C_VERTICAL_JUSTIFICATION]) != null)
                text.VerticalJustification = ParseJustification( e );

            if((e = node[ASN1ContextCodes.C_LINE_ORIENTATION]) != null)
                text.LineOrientation = ParseOrientation( e );

            if((e = node[ASN1ContextCodes.C_START_CORNER]) != null)
                text.StartCorner = ParseStartCorner( e );

            if((e = node[ASN1ContextCodes.C_TEXT_WRAPPING]) != null)
                text.TextWrapping = e.First.BoolValue;

            return text;
        }
    
        internal static FontAttributes FontAttributesBuilder(OctetStringNode node)
        {
            FontAttributes fontAttributes = new FontAttributes();
            String attributes = node.StringValue;

            String[] fields = attributes.Split('.');
           // string x = DecodeUtils.DecodeBase64(attributes);

            byte[] bytes = new ASCIIEncoding().GetBytes(attributes);
            //Convert.FromBase64String(attributes);

            if (fields.Length == 4 || fields.Length == 5)
            {

                if (fields[0] != "plain")
                    throw new Exception("1.06 only allows plain");

                fontAttributes.FontStyle = System.Drawing.FontStyle.Regular;

                int fontSize;
                if (!int.TryParse(fields[1], out fontSize))
                    fontSize = MHEGConstants.DefaultFontSize;

                fontAttributes.FontSize = fontSize;


                //fontAttributes = new System.Drawing.Font(
                //                    MHEGConstants.DefaultFontName,
                //                    fontSize-12,
                //                   System.Drawing.FontStyle.Regular
                //                   );

                int lineSpacing;
                if (!int.TryParse(fields[2], out lineSpacing))
                    lineSpacing = MHEGConstants.DefaultLineSpacing;

                fontAttributes.LineSpacing = lineSpacing;

                int letterSpace;
                if (!int.TryParse(fields[3], out letterSpace))
                    letterSpace = MHEGConstants.DefaultLetterSpace;

                fontAttributes.LetterSpace = letterSpace;


            }

            else if (bytes.Length == 5)
            {

                int fontStyle;
                
                try
                {
                    fontStyle = (int)bytes[0];
                }
                catch (Exception e)
                {
                    fontStyle = 0;
                }
                
                //need to reset bits 4-7
                //bit 2 is underline, bit 3 is outline
                System.Drawing.FontStyle style = System.Drawing.FontStyle.Regular;

                fontStyle &= 0xF;

                if ((fontStyle & 0x1) == 1)
                    style |= System.Drawing.FontStyle.Italic;

                if ((fontStyle & 0x2) == 1)
                    style |= System.Drawing.FontStyle.Bold;

                if ((fontStyle & 0x4) == 1)
                    style |= System.Drawing.FontStyle.Underline;

                if ((fontStyle & 0x8) == 1)
                    style |= System.Drawing.FontStyle.Strikeout;

                fontAttributes.FontStyle = style;

                int fontSize;
                // try
                // {
                fontSize = (int)bytes[1];
                // }
                // catch ( Exception e )
                //  {
                //      fontSize = MHEGConstants.DefaultFontSize;
                //  }
                //  finally
                //  {
                fontAttributes.FontSize = fontSize;
                // }

                //fontAttributes = new System.Drawing.Font(
                //                    MHEGConstants.DefaultFontName,
                //                    fontSize-12,
                //                    style);

                int lineSpacing;
                // try
                // {
                lineSpacing = (int)bytes[2];
                // }
                // catch ( Exception e )
                // {
                //     lineSpacing = MHEGConstants.DefaultLineSpacing;
                // }
                // finally
                // {
                //if ( lineSpacing != 28 ) throw new Exception( "oi" );
                fontAttributes.LineSpacing = lineSpacing;
                // }

                int letterSpace;
                // try
                // {
                letterSpace = (int)(((ushort)bytes[3] << 8) | (ushort)bytes[4]);
                //( ( ( int ) bytes [3] << 8 ) + ( int ) bytes [4] ); //- 0x7fff;
                // }
                // catch ( Exception e )
                // {
                //     letterSpace = MHEGConstants.DefaultLetterSpace;
                // }
                // finally
                // {
                fontAttributes.LetterSpace = letterSpace;
                // }

            }
            else throw new Exception("Can't Decode fontattribute");

            return fontAttributes;

        }
        
        private static Text.TextJustification ParseJustification(TaggedNode node)
        {
            try
            {
                return (Text.TextJustification) node.First.EnumValue;
            }
            catch (FormatException e)
            {
                return Text.TextJustification.Start;
            }
        }

        private static Text.TextOrientation ParseOrientation(TaggedNode node)
        {
             try
             {
                return ( Text.TextOrientation ) node.First.EnumValue;
             }
             catch ( FormatException e )
             {
                 return Text.TextOrientation.Horizontal;
             }
        }

        private static Text.TextStartCorner ParseStartCorner(TaggedNode node)
        {
            try
            {
                return (Text.TextStartCorner) node.First.EnumValue;
            }
            catch (FormatException e)
            {
                return Text.TextStartCorner.UpperLeft;
            }
        }
    }
}

